package model.base;

import java.util.List;

import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.Table;
import com.jfinal.plugin.activerecord.TableMapping;

import common.kit.KvCond;

@SuppressWarnings("serial")
public abstract class _BaseModel<M extends Model<M>> extends Model<M> {
	
	/**
	 * 获取表映射对象
	 * @return
	 */
	public Table getTable() {
		return TableMapping.me().getTable(getClass());
	}
	
	protected String generateShortName(String tableName) {
		String[] arr = tableName.split("_");
		StringBuffer sBuffer = new StringBuffer();
		for (String cur : arr) {
			sBuffer.append(cur.substring(0, 1));
		}
		return sBuffer.toString() ;
	}
	
	/**
	 * 根据某些字段组合查询一条数据
	 * shortName tableName 
	 * @param conf name= ?
	 * @return
	 */
	protected M findFirstBy(Kv cond) {
		String tableName = this.getTable().getName() ;
		Kv kv = new Kv();
		kv.set("tableName" , tableName);
		kv.set("shortName" , this.generateShortName(tableName));
		kv.set("cond" , cond);
		return this.template("findFirstBy", kv).findFirst() ;
	}

	protected M findFirstByEqual(String key , Object value) {
		KvCond kvCond = KvCond.byEqual(key , value);
		return findFirstBy(kvCond) ;
	}


	public List<M> findBy(String select , Kv cond , String orderBy) {
		Kv kv = getFindByKv(select, cond, orderBy);
		return this.template("findBy", kv).find() ;
	}
	
	public List<Record> dbFindBy(String select , Kv cond , String orderBy) {
		Kv kv = getFindByKv(select, cond, orderBy);
		return Db.template("findBy", kv).find() ;
	}
	
	public List<Record> dbFindBy(String select , Kv cond ) {
		return dbFindBy(select , cond , null ) ;
	}
	
	public Kv getFindByKv(String select , Kv cond , String orderBy) {
		String tableName = getTable().getName() ;
		String shortName = this.generateShortName(tableName);
		Kv kv = new Kv();
		select = StrKit.isBlank(select) ? shortName + ".*" : this.appendPrefix(select, shortName) ;
		kv.set("select" , select);
		kv.set("tableName" , tableName);
		kv.set("shortName" , shortName );
		kv.set("cond" , null == cond ? Kv.create() : cond );
		if (StrKit.notBlank(orderBy)){
			kv.set("orderBy" , this.appendPrefix(orderBy, shortName) );
		}
		return kv ;
	}
	
	private String appendPrefix(String columns , String shortName) {
		if (StrKit.isBlank(columns)) {
			return columns ;
		}
		String[] arr = columns.split(",");
		StringBuffer sBuffer = new StringBuffer();
		for (String order : arr) {
			if (!order.trim().startsWith(shortName + ".")) {
				order = shortName + "." + order.trim() ;
			}
			sBuffer.append(sBuffer.length()>0 ? "," : "").append(order);
		}
		return sBuffer.toString() ;
	}

	public List<M> findBy(String select , Kv cond) {
		return findBy(select , cond, null);
	}

	public List<M> findBy(Kv cond) {
		return findBy( null , cond, null);
	}
	
	public List<M> findBy(Kv cond , String orders) {
		return findBy( null , cond, orders);
	}

	public List<M> findByEqual(String keys , Object value) {
		return findByEqual(null , keys , value );
	}

	public List<M> findByEqualOrderBy(String keys , Object value , String orderBy) {
		return findByEqual(null , keys , value , orderBy);
	}

	public List<M> findByEqual( String select , String keys , Object value , String orderBy) {
		KvCond kvCond = KvCond.byEqual(keys , value) ;
		return findBy( select , kvCond, orderBy );
	}

    public List<M> findByEqual( String select , String keys , Object value) {
        KvCond kvCond = KvCond.byEqual(keys , value) ;
        return findBy( select , kvCond, null);
    }

	public List<M> findByNotLessThan(String keys , Object value) {
		return findByEqual(null , keys , value );
	}

	public List<M> findByNotLessThan( String select , String keys , Object value) {
		KvCond kvCond = KvCond.byNotLessThan(keys , value) ;
		return findBy( select , kvCond, null);
	}

	public List<M> findBy(String select) {
		return findBy(select , null , null);
	}
	
	public List<M> findOrderBy(String orders) {
		return findBy( null  , null , orders);
	}
	
	public List<M> findOrderBy(String select , String orders) {
		return findBy( select  , null , orders);
	}

	public int deleteBy(Kv cond) {
		String tableName = this.getTable().getName() ;
		Kv kv = new Kv();
		kv.set("tableName" , tableName);
		kv.set("cond" , cond);
		return Db.template("deleteBy", kv).update() ;
	}

	protected int deleteByEqual(String keys, Object value) {
		KvCond kvCond = KvCond.byEqual( keys , value) ;
		return deleteBy(kvCond) ;
	}
	
	protected Ret fail(String errMsg) {
		return Ret.fail("err" , errMsg);
	}
	
	protected Ret fail() {
		return Ret.fail("err" , "系统错误");
	}
	
	protected Ret ok() {
		return Ret.ok().set("err" , "成功");
	}
}
